home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1994-12-08 | 48.0 KB | 1,223 lines | [ TEXT/R*ch]
C.S.M.P. Digest Wed, 02 Dec 92 Volume 1 : Issue 220 Today's Topics: Think C debugger memory problems Self-modifying code (was Re: Best way to get A5...) Compressed PICT->JFIF Routines With Glue Bug in Think Pascal 4.0.1 debugger Self-modifying code The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly. The digest is a collection of article threads from the internet newsgroup comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi- regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. You can post articles to any newsgroup by mailing your article to newsgroup@ucbvax.berkeley.edu. So, to post an article to comp.sys.mac.programmer, you mail it to comp-sys-mac-programmer@ucbvax.berkeley.edu. Note the '-' instead of '.' in the newsgroup name. Each issue of the digest contains one or more sets of articles (called threads), with each set corresponding to a 'discussion' of a particular subject. The articles are not edited; all articles included in this digest are in their original posted form (as received by our news server at cs.uoregon.edu). Article threads are not added to the digest until the last article added to the thread is at least one month old (this is to ensure that the thread is dead before adding it to the digest). Article threads that consist of only one message are generally not included in the digest. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu [128.223.8.8] in the directory /pub/mac/csmp-digest. Be sure to read the file /pub/mac/csmp-digest/README before downloading any files. The most recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the directory /info-mac/digest/csmp. If you don't have ftp capability, the sumex archive has a mail server; send a message with the text '$MACarch help' (no quotes) to LISTSERV@ricevm1.rice.edu for more information. The digest is also available via email. Just send a note saying that you want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will automatically receive each new issue as it is created. Sorry, back issues are not available through the mailing list. Send administrative mail to mkelly@cs.uoregon.edu. ------------------------------------------------------- From: jlawrie@fraser.sfu.ca (John William Lawrie) Subject: Think C debugger memory problems Date: 23 Oct 92 04:29:01 GMT Organization: Simon Fraser University, Burnaby, B.C., Canada Hey guys, I was wondering if any of you would know how to give the think c debugger (version 5.3) more memory. I went to the finder (7.1) and gave it a minimum of 750k, and a preffered size of 1500k. (the suggested size is 250k). I then gave think c itself 3500k. Feeling that there was no way that there could be a shortage of memory, I ran the dubugger and soon got a "Debugger critically low on memory. Please end this debugging session as soon as possible" message. Quite confused, I checked the finder and was surprised to see that the dubugger was using almost all of the 600k (not 750k) available to it. I have ten megs of ram and my largest unused block was over 4 megs. What do I have to do to get the debugger to use all of the memory that I allocate to it? Is there some option in the think c application that I don't know about? Has anybody else encountered this problem? Any help would be greatly appreciated. john lawrie +++++++++++++++++++++++++++ From: perm@csd.uu.se (Per Mildner) Date: 23 Oct 92 09:39:40 Organization: Computing Science Dept.,Uppsala University, Sweden In article <jlawrie.719814541@sfu.ca> jlawrie@fraser.sfu.ca (John William Lawrie) writes: ... Feeling that there was no way that there could be a shortage of memory, I ran the dubugger and soon got a "Debugger critically low on memory. Please end this debugging session as soon as possible" message. Quite confused, I checked the finder and was surprised to ... You don't happen to use Desktop Textures 2.0? The Think C debugger has a bug that gobbles up a lot of memory if a fancy (eg large color) pattern is installed. This has prevented me from using my nice caffeine molecule pattern... - -- Per Mildner perm@CSD.UU.SE Computing Science Dept. tel: +46 18181049 Uppsala University, Sweden fax: +46 18521270 +++++++++++++++++++++++++++ From: aep@world.std.com (Andrew E Page) Date: 23 Oct 92 12:19:52 GMT Organization: The World Public Access UNIX, Brookline, MA You can reduce the amount of memory that the Debugger will need by switching off the debugging option on source files that you are not currently debugging. This will reduce the amount of data the the compiler will generate that the debugger has to maintain. - -- Andrew E. Page (Warrior Poet) | Decision and Effort The Archer and Arrow Mac Consultant | The difference between what we are Macintosh and DSP Technology | and what we want to be. +++++++++++++++++++++++++++ From: jlawrie@fraser.sfu.ca (John William Lawrie) Organization: Simon Fraser University, Burnaby, B.C., Canada Date: Sat, 24 Oct 1992 10:34:43 GMT nks for all of the responses to my question. I think I have solved the probl em. For some reason, After I ran the dubegger, the debugger would be reset to a minimum value of 250 k and a preffered of 600k. This happened to me several ti mes. So, I turned off all of my inits and tried again. This time it worked. U sing an exhaustive search technique, I determined that now utilities now menus version 4.0 was the cause of the problem. I don't know why, but when it is loaded, the problem appears. I also am using desktop textures. However, this does not cause any problems by itself. My systems is an LC with 10Megs. I am using the think Class Library but since I am relatively new to OOP, I have not yet done any memory manipulatio n. Well, anyhow, thanks for the responses. Hopefully I won't have any more problems. +++++++++++++++++++++++++++ From: phils@chaos.cs.brandeis.edu (Phil Shapiro) Date: 24 Oct 92 14:04:12 GMT Organization: Symantec Corp. >>>>> On 23 Oct 92 12:19:52 GMT, aep@world.std.com (Andrew E Page) said: > You can reduce the amount of memory that the Debugger will need > by switching off the debugging option on source files that you are > not currently debugging. This will reduce the amount of data the > the compiler will generate that the debugger has to maintain. Does this technique really work? I can't see how producing less debug information will help the Debugger, since it doesn't load the debug info on its heap. It instead requests the info from THINK C, which handles loading and unloading info. There was a problem in C 4.0 where the debug tables were limited to 64K; this restriction was removed in 5.0. The only restriction left is that projects cannot exceed 16Meg. -phil - -- Phil Shapiro Software Engineer Language Products Group Symantec Corporation Internet: phils@cs.brandeis.edu --------------------------- From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) Subject: Self-modifying code (was Re: Best way to get A5...) Date: 20 Oct 92 17:40:36 +1300 Organization: University of Waikato, Hamilton, New Zealand In article <1992Oct15.211147.15295@hobbes.kzoo.edu>, k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: > > (And self-modifying code is never a good idea unless every cycle counts, > and that's not the case here. I imagine the PowerPC will write-protect > code segments and--who knows?--may compile 680x0 code into its native > language and cache it, in which case self-modifying programs will be > very unhappy.) Nonsense. Self-modifying code should still work even in a system that translates code on the fly, so long as the code flushes caches properly. And systems that try to write-protect code segments soon find reasons for providing an escape. Want a (relatively) recent historical example? Check out the 80286 processor and OS/2 1.0. Why all this superstitious fear of self-modifying code? John von Neumann proved years ago that there were things that you couldn't do without it. As far as I'm concerned, that makes it a legitimate programming technique. Just as it is possible to do well-behaved transfers of control in your program without using exceptions or GOTOs, it is also possible to write well-structured self-modifying code. Examples available on request. Lawrence D'Oliveiro fone: +64-7-856-2889 Computer Services Dept fax: +64-7-838-4066 University of Waikato electric mail: ldo@waikato.ac.nz Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00 Just erotic. Nothing kinky. It's the difference between using a feather and using a chicken. -- Terry Pratchett, "Eric" +++++++++++++++++++++++++++ From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy) Organization: Kalamazoo College Date: Wed, 21 Oct 1992 14:25:26 GMT ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: >k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: >> >> I imagine the PowerPC will write-protect >> code segments and--who knows?--may compile 680x0 code into its native >> language and cache it, in which case self-modifying programs will be >> very unhappy. > >Nonsense. Self-modifying code should still work even in a system that >translates code on the fly, True. But what if it assumes code segments are write-protected and translates (say) a 'CODE' segment at a time into (say) its native machine language? I'm being very speculative here, but wouldn't such mass-translation, rather than instruction-at-a-time interpretation, be both feasible and desirable? >And systems >that try to write-protect code segments soon find reasons for providing an >escape. Want a (relatively) recent historical example? Check out the 80286 >processor and OS/2 1.0. The example's lost on me. Maybe you could briefly explain? In any case, we're talking about making this particular code compatible far into the future. On that barely-visible-far-off-on-the-horizon day when the MMU traps writes to code, our 1992 programs that don't know how to say "no, really, I know what I'm doing" will die horribly. >Why all this superstitious fear of self-modifying code? John von Neumann >proved years ago that there were things that you couldn't do without it. Yeah, OK--but we've put layers and layers of structure around what he called self-modifying code, and we're calling it a compiler. Compilers (and timing-critical code) aside, you don't _need_ self-modifying code, just like you don't _need_ a DBRA instruction. - -- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy Regrettably, my college's computer has once again deleted my in-box without even telling me who the senders were. If you sent me mail around Sunday night, contact me. Don't resend a long (100K) letter, it'll just delete it again. +++++++++++++++++++++++++++ From: bwilliam@iat.holonet.net (Bill Williams) Date: 24 Oct 92 05:40:33 GMT Organization: HoloNet (BBS: 510-704-1058) Jamie wrote >>And systems >>that try to write-protect code segments soon find reasons for providing an >>escape. Want a (relatively) recent historical example? Check out the 80286 >>processor and OS/2 1.0. >The example's lost on me. Maybe you could briefly explain? I am not a OS2 programmer but I think the issue he is pointing out is that one of the MOST CONCRETE MANDATES about OS/2 was going to be the absolute rule that all segements of memory were to be designated as either CODE or DATA to help design faster CPU's in the future (before all CPU's ended up with Harvard Style Data/Code individual cached bussses). PC Clone code writers argued about the issue a lot. typically the ravings were about **I FEEL IT IS CRITICAL TO HAVE SOME ABILITY FOR SELF MODIFYING CODE!!*** and such as that. Well It seems the programmers were right. OS/2 now allows code segment contents to be alterred without too much effort, I am told. I think that is what was meant in Lawrence D'Oliveiro's excellent post. Bill Williams +++++++++++++++++++++++++++ From: wisdom@picasso.ocis.temple.edu (Robert Wisdom) Date: 29 Oct 92 19:59:35 GMT Organization: Temple University This might be slightly off topic but... Can processors with caches use self modifying code? I would think that the change might occur in memory but not in the cache image. Am I missing something basic (Like OS designers are less stupid than I am?)? Robert --------------------------- From: dvan@spumco.cts.com (David Vandeven) Subject: Compressed PICT->JFIF Date: 29 Oct 92 00:07:33 GMT Organization: SPUMCO:Better living through wasted time A query directed at email or posted response: What is the difference between a compressed PICT and a JPEG? I am tired of playing with JPEG viewer, so I am going to write a batch converter. Can someone please post a summary of the file headers for each format? Thanks in advance. * Chief Systems Administrator: SPUMCO * David Vandeven ******************************************************** Systems Progammer * "I don't believe in Pinochle, I don't believe I'll * Deadhead * try: I do believe in Captain Crunch, for I am the * Cyberpunk * Frizzle Fry!" (dvan@spumco.cts.com) *PRIMUS!* * Zen Agnostic Guru ******************************************************** +++++++++++++++++++++++++++ From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) Date: 29 Oct 92 18:00:36 +1300 Organization: University of Waikato, Hamilton, New Zealand In article <D2150025.ri4kvb@spumco.cts.com>, dvan@spumco.cts.com (David Vandeven) writes: > > A query directed at email or posted response: What is the difference between > a compressed PICT and a JPEG? I am tired of playing with JPEG viewer, so I am > going to write a batch converter. QuickTime adds a new opcode to QuickDraw pictures. This opcode specifies a block of compressed data and an associated ImageDescription record--basically all the information the Image Compression Manager needs to decompress the data. There's no real need to worry about the format of this opcode. The Image Compression Manager provides all the routines you need to create compressed pictures, or to extract the compressed data--by intercepting QuickDraw bottlenecks--if you really want to. For the JPEG compressor, the compressed data takes the form of a JFIF data stream. Lawrence D'Oliveiro fone: +64-7-856-2889 Computer Services Dept fax: +64-7-838-4066 University of Waikato electric mail: ldo@waikato.ac.nz Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00 +++++++++++++++++++++++++++ From: dvan@spumco.cts.com (David Vandeven) Date: 29 Oct 92 09:47:39 GMT Organization: SPUMCO:Better living through wasted time In article <1992Oct29.180036.11788@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: > In article <D2150025.ri4kvb@spumco.cts.com>, dvan@spumco.cts.com (David Vandeven) writes: > > > > A query directed at email or posted response: What is the difference between > > a compressed PICT and a JPEG? I am tired of playing with JPEG viewer, so I am > > going to write a batch converter. > > QuickTime adds a new opcode to QuickDraw pictures. This opcode specifies > a block of compressed data and an associated ImageDescription record--basically > all the information the Image Compression Manager needs to decompress the > data. > > There's no real need to worry about the format of this opcode. The Image > Compression Manager provides all the routines you need to create compressed > pictures, or to extract the compressed data--by intercepting QuickDraw > bottlenecks--if you really want to. > > For the JPEG compressor, the compressed data takes the form of a JFIF data > stream. > > Lawrence D'Oliveiro fone: +64-7-856-2889 > Computer Services Dept fax: +64-7-838-4066 > University of Waikato electric mail: ldo@waikato.ac.nz > Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00 > Perhaps I wasn't specific enough... e I'm intersted in the file formats on disk for JFIF and compressed PICT. If I can figure out the differences I can easily write a batch converter. Thanks for the reply, though. * Chief Systems Administrator: SPUMCO * David Vandeven ******************************************************** Systems Progammer * "I don't believe in Pinochle, I don't believe I'll * Deadhead * try: I do believe in Captain Crunch, for I am the * Cyberpunk * Frizzle Fry!" (dvan@spumco.cts.com) *PRIMUS!* * Zen Agnostic Guru ******************************************************** +++++++++++++++++++++++++++ From: a-giles@uchicago.edu (Aaron Giles) Organization: University of Chicago High Energy Physics Date: Thu, 29 Oct 1992 15:39:28 GMT In article <D2150025.rkakkb@spumco.cts.com> dvan@spumco.cts.com (David Vandeven) writes: > In article <1992Oct29.180036.11788@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: >> In article <D2150025.ri4kvb@spumco.cts.com>, dvan@spumco.cts.com (David Vandeven) writes: >>> >>> A query directed at email or posted response: What is the >>> difference between a compressed PICT and a JPEG? I am tired of >>> playing with JPEG viewer, so I am going to write a batch converter. >> QuickTime adds a new opcode to QuickDraw pictures. This opcode >> specifies a block of compressed data and an associated >> ImageDescription record--basically all the information the Image >> Compression Manager needs to decompress the data. >> There's no real need to worry about the format of this opcode. The Image >> Compression Manager provides all the routines you need to create compressed >> pictures, or to extract the compressed data--by intercepting QuickDraw >> bottlenecks--if you really want to. >> For the JPEG compressor, the compressed data takes the form of a JFIF data >> stream. > Perhaps I wasn't specific enough... e I'm intersted in the > file formats on disk for JFIF and compressed PICT. If I can > figure out the differences I can easily write a batch > converter. If you're looking to write a file-based converter, you're asking for trouble. I tried this with JPEGView 0.9 and ran into a host of problems. What you need to do is goad QuickDraw into doing the work for you; it's not all that hard. A JPEG in a compressed PICT is just a JFIF with some extra information, so no conversion of the compressed data itself needs to be done. You'll need to write two routines; I call them WrapJFIF() and UnwrapJFIF(). WrapJFIF() takes a JFIF image and wraps it inside a compressed PICT structure; UnwrapJFIF() does the opposite. You'll also need a few support routines, MakeJFIFImageDesc(), AddJFIFHeader(), UnwrapStdPix() Here's a very sketchy outline of what you need to do for each. Note that this is all off the top of my head, so verify what you're doing before plunging blindly ahead. :-) Aaron a-giles@uchicago.edu - -------------------- #include <ImageCompression.h> PicHandle WrapJFIF(Ptr theData) { ImageDescriptionHandle theDesc; OpenCPicParams theParams; PicHandle thePict; if (!(theDesc = MakeJFIFImageDesc(theData))) return nil; // create an image description // set up theParams, set the GrafPort, and don't forget to // initialize the ClipRgn here! if (thePict = OpenCPicture(&theParams)) { DecompressImage(theData,...,theDesc,...); // note that this really does no // decompression; it just copies the // data // check for errors here ClosePicture(); // check for empty picFrame here } DisposeHandle(theDesc); return thePict; } ImageDescriptionHandle MakeJFIFImageDesc(theData) { // Just create a handle and fill in the fields; the // ImageCompression.h file should tell you enough of what you need // to know } Ptr gUnwrappedData; Ptr UnwrapJFIF(PicHandle thePict) { CGrafProcs theProcs; // Initialize theProcs to all point to dummy procedures, except for // the StdPixProc (aka newProc1), which should point to UnwrapStdPix // Then set to a valid GrafPort & change the grafProcs to point to // your new set of procs. gUnwrappedData = nil; // set to nil in case the PICT isn't compressed DrawPicture(thePict,...); // sends us to UnwrapStdPix // Restore the grafProcs of the GrafPort here return AddJFIFHeader(gUnwrappedData); // Make sure we've got a JFIF header } // I'm not sure of the parameters or type of this function; check // ImageDescription.h for details pascal void? UnwrapStdPix(PixMapPtr src, ...) { Ptr theData; if (GetCompressedPixMapInfo(src, &theData, ...) == noErr) { // Copy theData into a new pointer gUnwrappedData } } Ptr AddJFIFHeader(Ptr theData) { // This routine should check the data to make sure that there is a // JFIF header, and should make a new one if there isn't. We need // this because, although QuickTime's JPEG codec automatically puts // a JFIF header on, third-part JPEG codecs might not. } --------------------------- From: scott@mcl.ucsb.edu (Scott Bronson) Subject: Routines With Glue Date: 2 Oct 92 21:36:48 GMT In <winer.717955333@husc8> winer@husc8.harvard.edu (Adam Winer) writes: >wuertz@tik.ethz.ch (Andreas Wuertz) writes: >This brings up another point: what is the complete list of functions >with glue: I know for a fact that HOpenResFile() and the high-level >hierarchical functions like HOpen() have glue. Does anyone have a >full list? Here's an odd one that I ran across the other day. GetHandleSize has glue that checks to see if the returned value is negative, and if so it returns nil. How can one have a handle with *negative* handle size?? Sounds like fun. - Scott +++++++++++++++++++++++++++ From: keith@taligent.com (Keith Rollin) Organization: Taligent Date: Sat, 3 Oct 1992 10:14:43 GMT In article <scott.718061808@mcl>, scott@mcl.ucsb.edu (Scott Bronson) wrote: > > In <winer.717955333@husc8> winer@husc8.harvard.edu (Adam Winer) writes: > > >This brings up another point: what is the complete list of functions > >with glue: I know for a fact that HOpenResFile() and the high-level > >hierarchical functions like HOpen() have glue. Does anyone have a > >full list? Well, _you_ do. Just check your header files. Anything that doesn't have an equals sign after it ends up calling a library/glue routine. > > Here's an odd one that I ran across the other day. GetHandleSize has > glue that checks to see if the returned value is negative, and if so > it returns nil. How can one have a handle with *negative* handle > size?? Sounds like fun. The deal here (and with GetPtrSize) is that register D0 is used for a dual purpose. Normally, it holds the result code from the call, which is a negative number or zero. In the case of GetHandleSize, D0 is also used to return the size of the handle. Therefore, the glue checks to see if the return value is negative. If it is, then an error occured and zero is returned as the handle size. The Inside Macs indicate this in their discussions of the GetHandleSize and GetPtrSize. - ----- Keith Rollin Phantom Programmer Taligent, Inc. +++++++++++++++++++++++++++ From: michael@otago.ac.nz Date: 5 Oct 92 03:32:55 GMT Organization: University of Otago, Dunedin, New Zealand >>wuertz@tik.ethz.ch (Andreas Wuertz) writes: > >>This brings up another point: what is the complete list of functions >>with glue: I know for a fact that HOpenResFile() and the high-level >>hierarchical functions like HOpen() have glue. Does anyone have a >>full list? This would be good and brings up another point: some of the quantity of glue you get on occasion can be a bit of a shock, especially if you are trying to write a minimum-size application like the UpdateMaker stand-alones. I already go through some contortions to avoid all the MPW initialisation stuff - I still don't know what the heck that does, but I don't seem to need it. But then the glue you get when you call _Gestalt is just amazing, and if you have just gone to the trouble of checking that you can do so safely it is rather annoying to find that the glue checks again and fakes things if the trap isn't present....this is all very well but it would be nicer if it was documented somewhere. Michael(tm) Hamel, Computing Services Centre, University of Otago, New Zealand DITHERINGTON (n.) Sudden access of panic experienced by one who realises that he is being drawn inexorably into a clabby (q.v.) conversation, i.e. one he has no hope of enjoying, benefitting from or understanding. +++++++++++++++++++++++++++ From: keith@taligent.com (Keith Rollin) Date: 5 Oct 92 19:35:57 GMT Organization: Taligent In article <1992Oct5.092320.34@otago.ac.nz>, michael@otago.ac.nz wrote: > > But then the > glue you get when you call _Gestalt is just amazing, and if you have just gone > to the trouble of checking that you can do so safely it is rather annoying to > find that the glue checks again and fakes things if the trap isn't > present....this is all very well but it would be nicer if it was documented > somewhere. If you check for the existance of _Gestalt yourself and are prepared to deal with its not being implemented, then you don't need the glue. Set the SystemSevenOrLater flag when compiling, and you'll call the trap directly. Here's the interface from GestaltEqu.h. #if SystemSevenOrLater #pragma parameter __D0 Gestalt(__D0,__A1) pascal OSErr Gestalt(OSType selector,long *response) = {0xA1AD,0x2288}; #else pascal OSErr Gestalt(OSType selector,long *response); #endif Pascal doesn't seem to work this way (the headers indicate that it always calls the glue), so if you use Pascal you might be out of luck. There are a number of traps like this -- just search for "SystemSevenOrLater" in your headers. For example, FindFolder can either call a library routine or the trap. - ----- Keith Rollin Phantom Programmer Taligent, Inc. +++++++++++++++++++++++++++ From: michael@otago.ac.nz Date: 29 Oct 92 00:31:27 GMT Organization: University of Otago, Dunedin, New Zealand >>wuertz@tik.ethz.ch (Andreas Wuertz) writes: > >>This brings up another point: what is the complete list of functions >>with glue: I know for a fact that HOpenResFile() and the high-level >>hierarchical functions like HOpen() have glue. Does anyone have a >>full list? This would be good and brings up another point: some of the quantity of glue you get on occasion can be a bit of a shock, especially if you are trying to write a minimum-size application like the UpdateMaker stand-alones. I already go through some contortions to avoid all the MPW initialisation stuff - I still don't know what the heck that does, but I don't seem to need it. But then the glue you get when you call _Gestalt is just amazing, and if you have just gone to the trouble of checking that you can do so safely it is rather annoying to find that the glue checks again and fakes things if the trap isn't present....this is all very well but it would be nicer if it was documented somewhere. Michael(tm) Hamel, Computing Services Centre, University of Otago, New Zealand DITHERINGTON (n.) Sudden access of panic experienced by one who realises that he is being drawn inexorably into a clabby (q.v.) conversation, i.e. one he has no hope of enjoying, benefitting from or understanding. --------------------------- From: kemper@millelac.rhrk.uni-kl.de (Michael Kemper [Informatik]) Subject: Bug in Think Pascal 4.0.1 debugger Date: 21 Oct 92 09:46:25 GMT Organization: University of Kaiserslautern (Germany) Hi there, I discovered a bug in the Think Psacal 4.0.1 debugger. When you use the debugger to look at gSystem in the TCL, you will see a packed record starting with nine booleans, followed by an integer. The first eight booleans are packed into the first byte of the record, the ninth is packed into the second byte, the integer is the third and fourth byte. Setting the first eight booleans to true or false doesn't make any trouble, but setting the ninth (gSystem.hasFPU) to true doesn't seem to work. Looking closer you can see, that the corresponding bit of the second byte is correctly set, but the debugger always shows that boolean as false. I don't know if this bug occurs at other places too, but it is very likely, that LightsBug has difficulties with that much booleans. I hope someone at Symantec reads this. - --------------------------------------------------- Michael Kemper, not speaking for anyone but himself - --------------------------------------------------- +++++++++++++++++++++++++++ From: David_B._Lamkins@fourd.com Date: 24 Oct 92 20:44:19 GMT Organization: 4th Dimension BBS Michael Kemper writes of a problem with the THINK Pascal 4.0.1 debugger: <<I discovered a bug in the Think Psacal 4.0.1 debugger. When you use the debugger to look at gSystem in the TCL, you will see a packed record starting with nine booleans, followed by an integer. The first eight booleans are packed into the first byte of the record, the ninth is packed into the second byte, the integer is the third and fourth byte. Setting the first eight booleans to true or false doesn't make any trouble, but setting the ninth (gSystem.hasFPU) to true doesn't seem to work. Looking closer you can see, that the corresponding bit of the second byte is correctly set, but the debugger always shows that boolean as false. I don't know if this bug occurs at other places too, but it is very likely, that LightsBug has difficulties with that much booleans. I hope someone at Symantec reads this. >> I don't know whether it has anything to do with booleans, but I have seen instances of Lightsbug failing to report the proper values for globals, particularly in large programs with deeply nested stack frames. What I _have_ seen is that Lightsbug gets confused about the address of the globals. If I move the memory dump window to a little bit lower address when examining a global that Lightsbug gets confused about, I see the proper values (only in the memory dump, though). The offsets I've seen range were two bytes in one case, and thirty-two bytes in another. These problems are repeatable, and I've called THINK tech support -- they have not had a prior report of such problems. Dave ******************************************************************** System: fourd.com Phone: 617-494-0565 Cute quote: Being a computer means never having to say you're sorry ******************************************************************** +++++++++++++++++++++++++++ From: siegel@world.std.com (Rich Siegel) Organization: GCC Technologies Date: Mon, 26 Oct 1992 13:27:11 GMT In article <1992Oct24.154419.11156@fourd.com> David_B._Lamkins@fourd.com writes: > >I don't know whether it has anything to do with booleans, but I have seen >instances of Lightsbug failing to report the proper values for globals, >particularly in large programs with deeply nested stack frames. What I _have_ >seen is that Lightsbug gets confused about the address of the globals. If I >move the memory dump window to a little bit lower address when examining a >global that Lightsbug gets confused about, I see the proper values (only in >the memory dump, though). The offsets I've seen range were two bytes in one >case, and thirty-two bytes in another. These problems are repeatable, and I've >called THINK tech support -- they have not had a prior report of such >problems. Actually, the symptoms manifest themselves when you're trying to look at globals in a unit which has an implementation-USES clause, and one or more of the USED units have globals in the interface-part. LightsBug's base address gets out of sync by the amount of globals in the used units. Observe always has the right answer, though. R. - -- - ----------------------------------------------------------------------- Rich Siegel Internet: siegel@world.std.com Software Engineer & Toolsmith GCC Technologies +++++++++++++++++++++++++++ From: David_B._Lamkins@fourd.com Organization: 4th Dimension BBS Date: Thu, 29 Oct 1992 21:41:01 EST <<Actually, the symptoms manifest themselves when you're trying to look at globals in a unit which has an implementation-USES clause, and one or more of the USED units have globals in the interface-part. LightsBug's base address gets out of sync by the amount of globals in the used units. Observe always has the right answer, though.>> Thanks, Rich. That's exactly what's happening! Do you know of workarounds, other than strict avoidance? Dave ******************************************************************** System: fourd.com Phone: 617-494-0565 Cute quote: Being a computer means never having to say you're sorry ******************************************************************** --------------------------- Subject: Self-modifying code Date: 21 Oct 92 21:16:11 GMT Organization: Royal Institute of Technology, Stockholm, Sweden > ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: > Compilers (and timing-critical code) aside, you don't _need_ > self-modifying code, just like you don't _need_ a DBRA instruction. No, there's more to it than time-criticality. Think of the number of times we get questions in this newsgroup about how to pass arguments (A5 values, and other things) to completion routines, Time Manager tasks and the like. No, you don't need self-modifying code for that. Just declare your parameter block as: typedef struct MyParam { long theA5 ; ParamBlock realBlock ; } MyParam ; Then stuff your A5 (or whatever) in theA5, fill in the parameter block, and install it with & myParam . realBlock. Since the completion routines get access to the parameter block (usually in A0 or A1, right?) it also has access to the A5 you wanted. The ONLY thing I can see that requires write access to a code segment, is a code resource that wants globals, although the component manager can give you that now! Left is only your _Gestalt selector functions... (I want a _Gestalt installer proc that lets me install a VALUE to be returned instead of a function to create that value !) - -- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Suedoise (not french speaking) -- -- I don't fear death, it's dying that scares me. +++++++++++++++++++++++++++ From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) Date: 22 Oct 92 09:22:57 +1300 Organization: University of Waikato, Hamilton, New Zealand In article <1992Oct21.142526.4403@hobbes.kzoo.edu>, k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: > ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: >>k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: >>> >>> I imagine the PowerPC will write-protect >>> code segments and--who knows?--may compile 680x0 code into its native >>> language and cache it, in which case self-modifying programs will be >>> very unhappy. >> >>Nonsense. Self-modifying code should still work even in a system that >>translates code on the fly, > > True. But what if it assumes code segments are write-protected and > translates (say) a 'CODE' segment at a time into (say) its native > machine language? I'm being very speculative here, but wouldn't such > mass-translation, rather than instruction-at-a-time interpretation, be > both feasible and desirable? You're right. This is all very speculative. I think I'll just sit and wait to see how the new machines actually behave. Just consider how many sales they're likely to lose if they break THINK C and THINK Pascal... >>And systems >>that try to write-protect code segments soon find reasons for providing an >>escape. Want a (relatively) recent historical example? Check out the 80286 >>processor and OS/2 1.0. > > The example's lost on me. Maybe you could briefly explain? The 80286 protection model allows for "code" segments and "data" segments. "Code" segments are executable, and may also have read access, or no read access. "Data" segments are always readable, and may optionally be writable. Code segments may not be writable. OS/2 1.0, which I tend to think of as a heroic exercise in trying to do something useful with the 80286 protection model, got around this by letting you "alias" a code segment as a data segment. What this meant was you had two segment descriptors, both referencing the same block of memory. This let you write into code segments, which the underlying protection model would not do. > >>Why all this superstitious fear of self-modifying code? John von Neumann >>proved years ago that there were things that you couldn't do without it. > > Yeah, OK--but we've put layers and layers of structure around what he > called self-modifying code, and we're calling it a compiler. > Compilers (and timing-critical code) aside, you don't _need_ > self-modifying code, just like you don't _need_ a DBRA instruction. No, there's more to it than time-criticality. Think of the number of times we get questions in this newsgroup about how to pass arguments (A5 values, and other things) to completion routines, Time Manager tasks and the like. Lawrence D'Oliveiro fone: +64-7-856-2889 Computer Services Dept fax: +64-7-838-4066 University of Waikato electric mail: ldo@waikato.ac.nz Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00 "Ah," he said, feeling a familiar and almost comforting sense of helpless dread sweep over him. -- Terry Pratchett, "Eric" +++++++++++++++++++++++++++ From: absurd@apple.apple.com (Tim Dierks, software saboteur) Date: 21 Oct 92 22:30:56 GMT Organization: MacDTS Marauders In article <1992Oct22.092257.11585@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) wrote: > > In article <1992Oct21.142526.4403@hobbes.kzoo.edu>, k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: > > ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: > >>Why all this superstitious fear of self-modifying code? John von Neumann > >>proved years ago that there were things that you couldn't do without it. > > > > Yeah, OK--but we've put layers and layers of structure around what he > > called self-modifying code, and we're calling it a compiler. > > Compilers (and timing-critical code) aside, you don't _need_ > > self-modifying code, just like you don't _need_ a DBRA instruction. > > No, there's more to it than time-criticality. Think of the number of times > we get questions in this newsgroup about how to pass arguments (A5 values, > and other things) to completion routines, Time Manager tasks and the like. There's a distinct difference between self-modifying code and storing data mixed in with your code. I would recommend, almost universally, against the first, but the second is sometimes necessary (although best avoided). Self-modifying code would be if you wrote code like the following: MOVE.L #$12345678,D0 ; Constant will be changed later and attempted to replace the constant value $12345678 with a different value as the program ran; you're actually modifying the instruction the processor executes. If instead you do the following: MOVE.L Storage,D0 BRA.S @1 Storage: DC.L $12345678 @1: ;code continues And modify the Storage value as the program runs, you're not modifying the instruction; you're just storing the value near your code. This is significantly safer than actual self-modifying code, but much more dangerous (in future compatibility terms) than storing your values as part of superclasses of parameter blocks. Sometimes you need to use PC-relative storage; INITs that patch traps are the most common example. If you can use the "add a field to a parameter block" method, you're better off. I realize it's less than fully documented, but pointers to parameter blocks are passed to VBLs and Time Manager tasks; a VBL gets a pointer to its task record in register A0; a completion routine gets a pointer to its parameter block in A0; Time Manager tasks get pointers to their records in A1. You can count on all these things; they're the safest way to access external values from these kinds of task. Enjoy, Tim Dierks MacDTS, but I sneak in the trees +++++++++++++++++++++++++++ From: resnick@cogsci.uiuc.edu (Pete Resnick) Date: 22 Oct 92 08:56:46 GMT Organization: University of Illinois at Urbana ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: >In article <D88-JWA.92Oct21221611@byse.nada.kth.se>, d88-jwa@byse.nada.kth.se (Jon Wdtte) writes: >>> ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes: >> >> No, there's more to it than time-criticality. Think of the number of times >> we get questions in this newsgroup about how to pass arguments (A5 values, >> and other things) to completion routines, Time Manager tasks and the like. > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >> >> No, you don't need self-modifying code for that. >Yes you do. Why? You can pass stuff on the bottom of the TMTask in a Time Manager routine. Most other things, you can store data in your code space without having to resort to ever modifying instructions in memory. Again, I ask, why? pr - -- Pete Resnick (...so what is a mojo, and why would one be rising?) Graduate assistant - Philosophy Department, Gregory Hall, UIUC System manager - Cognitive Science Group, Beckman Institute, UIUC Internet: resnick@cogsci.uiuc.edu +++++++++++++++++++++++++++ From: piovanel@ghost.dsi.unimi.it (marco piovanelli) Date: 23 Oct 92 12:47:02 GMT Organization: Computer Science Dep. - Milan University absurd@apple.apple.com (Tim Dierks, software saboteur) writes: >There's a distinct difference between self-modifying code and storing >data mixed in with your code. I would recommend, almost universally, >against the first, but the second is sometimes necessary (although >best avoided). I have a question that is only loosely connected with the above. It has to do with 'embedded' MDEF (or LDEF, for that matter) resources. The technique used by the TCL involves modifying a MDEF stub resource *AFTER* it's been loaded into memory (and potentially cached by the processor, I assume) to make it point to your application embedded defproc code. On a 68040 machine (with write-back cache), this requires flushing the code cache soon after modifying the stub. Furthermore, this technique would break if code resources were write- protected. Now, what about this slightly different technique: you load your menu as always (with _GetRMenu) and have your menu record pointing to the standard textProc MDEF. Then you build a stub from scratch (no MDEF resources), fill it with the appropriate JMP instruction and replace the menuProc field in the menu record. Something like this: FUNCTION MakeDefProcStub(entryPoint: ProcPtr): Handle; TYPE DefProcStub = RECORD jumpInstruction: Integer; jumpAddress: ProcPtr; END; DefProcStubPtr = ^DefProcStub; DefProcStubH = ^DefProcStubPtr; VAR theStub: DefProcStubH; BEGIN theStub := DefProcStubH(NewHandle(SizeOf(DefProcStub))); theStub^^.jumpInstruction := $4EF9; theStub^^.jumpAddress := entryPoint; MakeDefProcStub := theStub; END; FUNCTION GetCustomMenu(menuID: Integer): MenuHandle; VAR theMenu: MenuHandle; BEGIN theMenu := GetMenu(menuID); theMenu^^.menuProc := MakeDefProcStub(@MyEmbeddedMDEF); CalcMenuSize(theMenu); GetCustomMenu := theMenu; END; I tried this technique on a 68030 machine and it worked fine. Would it work on a 68040 without having to flush the cache? Thank you in advance for any comments / suggestions. Sorry if this is a long post. Please reply by e-mail. +++++++++++++++++++++++++++ From: absurd@apple.apple.com (Tim Dierks, software saboteur) Date: 23 Oct 92 19:00:35 GMT Organization: MacDTS Marauders In article <1992Oct23.124702.4648@ghost.dsi.unimi.it>, piovanel@ghost.dsi.unimi.it (marco piovanelli) wrote: > > absurd@apple.apple.com (Tim Dierks, software saboteur) writes: > > >There's a distinct difference between self-modifying code and storing > >data mixed in with your code. I would recommend, almost universally, > >against the first, but the second is sometimes necessary (although > >best avoided). [Question regarding using the 6-byte resource trick] > theStub := DefProcStubH(NewHandle(SizeOf(DefProcStub))); > theStub^^.jumpInstruction := $4EF9; > theStub^^.jumpAddress := entryPoint; [...] > I tried this technique on a 68030 machine and it worked fine. > Would it work on a 68040 without having to flush the cache? No; if you're creating instructions, you need to flush the cache on the 68040 or risk big trouble. This is regardless of where the memory that you're modifying is. Just call _FlushInstructionCache on a 68040 and you'll be all right. Tim Dierks MacDTS is only skin deep. +++++++++++++++++++++++++++ From: paul@taniwha.UUCP (Paul Campbell) Date: 28 Oct 92 18:48:20 GMT Organization: Taniwha Systems Design piovanel@ghost.dsi.unimi.it (marco piovanelli) wrote: > > theStub := DefProcStubH(NewHandle(SizeOf(DefProcStub))); > theStub^^.jumpInstruction := $4EF9; > theStub^^.jumpAddress := entryPoint; > I tried this technique on a 68030 machine and it worked fine. > Would it work on a 68040 without having to flush the cache? It worked on the '030 because you were lucky (previous instructions from that same address weren't in the instruction cache). It might work on the '040 if you are lucky too (but less likely because of the write-back cache). Moral of the story .... you HAVE to call FlushInstructionCache() here on both CPUs (not all systems have it implemented - either see if the _HWPriv trap is implemented or use a BlockMove() of more than 12 bytes to do the same thing). Paul - -- Paul Campbell UUCP: ..!mtxinu!taniwha!paul AppleLink: CAMPBELL.P "Since I've been Gov. of Texas the Berlin Wall has fallen ..." Anne Richards +++++++++++++++++++++++++++ From: ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) Date: 29 Oct 92 18:03:58 +1300 Organization: University of Waikato, Hamilton, New Zealand In article <1287@taniwha.UUCP>, paul@taniwha.UUCP (Paul Campbell) writes: > > (not all systems have [FlushInstructionCache] implemented - either see if > the _HWPriv trap is implemented or use a BlockMove() of more than 12 > bytes to do the same thing). I think HWPriv is implemented on all 68020-or-better Macs running System 6.0 or later. In other words, unless you're keen on compatibility with antediluvian systems, you can assume that, if your CPU needs the services of HWPriv, it's got it. Lawrence D'Oliveiro fone: +64-7-856-2889 Computer Services Dept fax: +64-7-838-4066 University of Waikato electric mail: ldo@waikato.ac.nz Hamilton, New Zealand 37^ 47' 26" S, 175^ 19' 7" E, GMT+13:00 +++++++++++++++++++++++++++ From: zobkiw@world.std.com (Joe Zobkiw) Organization: The World Public Access UNIX, Brookline, MA Date: Thu, 29 Oct 1992 13:46:59 GMT If you are into low memory globals you can always check the byte at CPUFlag (0x12f), If it is 04 you are on an '040, 03 means '030, etc. This is what BlockMove looks at (I think it was BlockMove, one of the instructions that flushes the cache checks this lomem) - -- - ------------------------------------------------------------- joe zobkiw zobkiw@world.std.com aol: aflzobkiw macintosh.midi.synthesis.c.oop.asm.communications.graphics... +++++++++++++++++++++++++++ From: Quinn <quinn@cs.uwa.edu.au> Organization: The University of Western Australia Date: Fri, 30 Oct 1992 00:57:51 GMT In article <1992Oct29.180358.11789@waikato.ac.nz> Lawrence D'Oliveiro, ldo@waikato.ac.nz writes: >I think HWPriv is implemented on all 68020-or-better Macs running System >6.0 or later. In other words, unless you're keen on compatibility with >antediluvian systems, you can assume that, if your CPU needs the services >of HWPriv, it's got it. Does anyone know what accelerator cards do with this? I mean if you jam a '030 into a Classic will it have _HWPriv implemented? Do the accelerator vendors provide an INIT^H^H^H^H system extension that implements the trap? Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> "Support HAVOC!" Department of Computer Science, The University of Western Australia -- Some antediluvian terminology. --------------------------- End of C.S.M.P. Digest **********************